package com.yfree.utils.net;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.net.Uri;
import android.text.TextUtils;
import android.widget.ImageView;

import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import com.bumptech.glide.request.target.BitmapImageViewTarget;
import com.yfree.YConfig;
import com.yfree.activities.YActivity;
import com.yfree.application.YApplication;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.MessageDigest;

public class YImageUtils {
    @Deprecated
    public static void yDisplay(ImageView imageView, String url) {
        if (TextUtils.isEmpty(url)) {
            if (YConfig.isSetPicDefault) {
                imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                imageView.setImageResource(YConfig.loadingFailImage);
            }
        } else
            YApplication.getFinalBitmap().display(imageView, url);
    }

    public static void yDisplay(YActivity activity, ImageView imageView, String url) {
        yDisplay(activity, imageView, url, true);
    }

    public static void yDisplay(YActivity activity, ImageView imageView, String url, boolean cache) {
        if (imageView == null) {
            return;
        } else if (TextUtils.isEmpty(url)) {
            if (YConfig.isSetPicDefault)
                imageView.setImageResource(YConfig.loadingFailImage);
        } else {
            if (cache) {
                if (YConfig.isSetPicDefault)
                    Glide.with(activity).load(url).placeholder(YConfig.loadingImage).error(YConfig.loadingFailImage).into(imageView);
                else
                    Glide.with(activity).load(url).into(imageView);
            } else {
                if (YConfig.isSetPicDefault)
                    Glide.with(activity).load(url).placeholder(YConfig.loadingImage).error(YConfig.loadingFailImage).diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true).into(imageView);
                else
                    Glide.with(activity).load(url).diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true).into(imageView);
            }
        }
    }

    public static void yDisplayCircle(final YActivity activity, final ImageView imageView, String url) {
        yDisplayCircle(activity, imageView, url, true);
    }

    public static void yDisplayCircle(final YActivity activity, final ImageView imageView, String url, boolean cache) {
        if (cache) {
            if (TextUtils.isEmpty(url)) {
                if (YConfig.isSetPicDefault)
                    Glide.with(activity).asBitmap().load(YConfig.loadingFailImage).centerCrop().into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCircular(true);
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
            } else {
                if (YConfig.isSetPicDefault)
                    Glide.with(activity).asBitmap().load(url).centerCrop().placeholder(YConfig.loadingImage).error(YConfig.loadingFailImage).into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCircular(true);
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
                else
                    Glide.with(activity).asBitmap().load(url).centerCrop().into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCircular(true);
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
            }
        } else {
            if (TextUtils.isEmpty(url)) {
                if (YConfig.isSetPicDefault)
                    Glide.with(activity).asBitmap().load(YConfig.loadingFailImage).centerCrop().diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true).into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCircular(true);
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
            } else {
                if (YConfig.isSetPicDefault)
                    Glide.with(activity).asBitmap().load(url).centerCrop().diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true).placeholder(YConfig.loadingImage).error(YConfig.loadingFailImage).into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCircular(true);
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
                else
                    Glide.with(activity).asBitmap().load(url).centerCrop().diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true).into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCircular(true);
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
            }
        }
    }

    public static void yDisplayCorner(final YActivity activity, final ImageView imageView, String url, int radius) {
        yDisplayCorner(activity, imageView, url, radius, true);
    }

    public static void yDisplayCorner(final YActivity activity, final ImageView imageView, String url, int radius, boolean cache) {
        if (cache) {
            if (TextUtils.isEmpty(url)) {
                if (YConfig.isSetPicDefault)
                    Glide.with(activity).asBitmap().load(YConfig.loadingFailImage).centerCrop().into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCornerRadius(activity.yGetDpByPx(radius));
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
            } else {
                if (YConfig.isSetPicDefault)
                    Glide.with(activity).asBitmap().load(url).centerCrop().placeholder(YConfig.loadingImage).error(YConfig.loadingFailImage).into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCornerRadius(activity.yGetDpByPx(radius));
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
                else
                    Glide.with(activity).asBitmap().load(url).centerCrop().into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCornerRadius(activity.yGetDpByPx(radius));
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
            }
        } else {
            if (TextUtils.isEmpty(url)) {
                if (YConfig.isSetPicDefault)
                    Glide.with(activity).asBitmap().load(YConfig.loadingFailImage).centerCrop().diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true).into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCornerRadius(activity.yGetDpByPx(radius));
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
            } else {
                if (YConfig.isSetPicDefault)
                    Glide.with(activity).asBitmap().load(url).centerCrop().diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true).placeholder(YConfig.loadingImage).error(YConfig.loadingFailImage).into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCornerRadius(activity.yGetDpByPx(radius));
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
                else
                    Glide.with(activity).asBitmap().load(url).centerCrop().diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true).into(new BitmapImageViewTarget(imageView) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            RoundedBitmapDrawable circularBitmapDrawable = RoundedBitmapDrawableFactory.create(activity.getResources(), resource);
                            circularBitmapDrawable.setCornerRadius(activity.yGetDpByPx(radius));
                            imageView.setImageDrawable(circularBitmapDrawable);
                        }
                    });
            }
        }
    }

    public static Bitmap yCompressBitmap(Bitmap srcBitmap) {
        return yCompressByQuality(yCompressBySize(srcBitmap));
    }

    public static Bitmap yDecodeSampledBitmapFromUri(Context context, Uri imageUri) {
        try {
            final Options options = new Options();
            InputStream iStream = context.getContentResolver().openInputStream(imageUri);
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(iStream, null, options);
            if (iStream != null)
                iStream.close();
            options.inSampleSize = yCalculateInSampleSize(options);
            options.inJustDecodeBounds = false;
            iStream = context.getContentResolver().openInputStream(imageUri);
            Bitmap bitmap = BitmapFactory.decodeStream(iStream, null, options);
            if (iStream != null) {
                iStream.close();
            }
            return bitmap;
        } catch (Exception e) {
            return null;
        }
    }

    public static Bitmap yDecodeSampledBitmapFromCamare(String filePath) {
        try {
            final Options options = new Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(filePath, options);
            options.inSampleSize = yCalculateInSampleSize(options);
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeFile(filePath, options);
        } catch (Exception e) {
            return null;
        }
    }

    private static Bitmap yCompressBySize(Bitmap image) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            image.compress(Bitmap.CompressFormat.JPEG, YConfig.bitmapQuality, baos);
            byte[] bs = baos.toByteArray();
            baos.flush();
            baos.close();
            if (!image.isRecycled())
                image.recycle();
            Options opts = new Options();
            opts.inSampleSize = 1;
            opts.inJustDecodeBounds = false;
            opts.inPreferredConfig = Config.RGB_565;
            opts.inInputShareable = true;
            opts.inPurgeable = true;
            Bitmap bitPic = null;
            do {
                if (bitPic != null) {
                    if (!bitPic.isRecycled())
                        bitPic.recycle();
                    opts.inSampleSize++;
                }
                ByteArrayInputStream isBm = new ByteArrayInputStream(bs);
                bitPic = BitmapFactory.decodeStream(isBm, null, opts);
                isBm.close();
            } while (bitPic.getWidth() > YConfig.maxBitmapSize
                    || bitPic.getHeight() > YConfig.maxBitmapSize);
            return bitPic;// 压缩好比例大小后再进行质量压缩
        } catch (Exception e) {
            return null;
        }
    }

    private static Bitmap yCompressByQuality(Bitmap image) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            image.compress(Bitmap.CompressFormat.JPEG, YConfig.bitmapQuality,
                    baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
            int options = 100;
            while (baos.toByteArray().length / 1024 > YConfig.maxBitmapKB) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
                baos.reset();// 重置baos即清空baos
                image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
                options -= 5;// 每次都减少5
            }
            byte[] bs = baos.toByteArray();
            baos.flush();
            baos.close();
            if (!image.isRecycled())
                image.recycle();
            ByteArrayInputStream isBm = new ByteArrayInputStream(bs);// 把压缩后的数据baos存放到ByteArrayInputStream中
            Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
            isBm.close();
            return bitmap;
        } catch (Exception e) {
            return null;
        }
    }

    private static int yCalculateInSampleSize(Options options) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > YConfig.maxBitmapSize || width > YConfig.maxBitmapSize) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) >= YConfig.maxBitmapSize && (halfWidth / inSampleSize) >= YConfig.maxBitmapSize)
                inSampleSize += 1;
        }
        return inSampleSize;
    }

    public static class YGlideRoundTransform extends BitmapTransformation {
        private float radius = 0f;

        public YGlideRoundTransform(Context context, int dp) {
            super();
            this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
        }

        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            return roundCrop(pool, toTransform);
        }

        private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
            if (source == null) return null;
            Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
            if (result == null)
                result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(result);
            Paint paint = new Paint();
            paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
            paint.setAntiAlias(true);
            RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
            canvas.drawRoundRect(rectF, radius, radius, paint);
            return result;
        }

        @Override
        public void updateDiskCacheKey(MessageDigest messageDigest) {

        }
    }
}
